package com.lzy.sso.cas.store.impl;

import com.lzy.sso.cas.cache.LRUCache;
import com.lzy.sso.cas.pojo.Identification;
import com.lzy.sso.cas.store.IdentificationStorage;
import com.lzy.sso.cas.store.TokenManagement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.concurrent.TimeUnit;

/**
 * @Author: lzy
 * @Date: 2022/4/26 20:09
 * @Description: 使用redis管理
 */

//@Component
//@ConditionalOnProperty(name = "lzy.cas.session.store",havingValue = "redis")
public class RedisTokenManagement implements TokenManagement {
    public static final String TOKEN_PREFIX="lzy:token:";

    //缓存 减少网络传输
    private LRUCache<Identification> tokenMap=new LRUCache<>(64);

    @Autowired
    @Qualifier("casRedisTemplate")
    private RedisTemplate<String,Object> redisTemplate;

    /**
     * 先取缓存 再取redis
     * @param token
     * @return
     */
    @Override
    public boolean exists(String token) {
        boolean exist = tokenMap.containsKey(token);
        if(exist)
            return true;

        IdentificationStorage ids =(IdentificationStorage) redisTemplate.opsForValue().get(TOKEN_PREFIX+token);
        if(ids!=null){
            tokenMap.put(token,ids.convert());
            return true;
        }
        return false;
    }

    /**
     * 添加到redis与本地缓存中
     * @param token
     * @param identification
     * @param expires
     */
    @Override
    public void addToken(String token,Identification identification, long expires) {
        boolean res = redisTemplate.opsForValue().setIfAbsent(TOKEN_PREFIX+token,
                                                new IdentificationStorage(identification),
                                                expires, TimeUnit.SECONDS);
        if(!res){
            throw new RuntimeException("添加token失败!");
        }

        tokenMap.put(token, identification);
    }

    @Override
    public void addToken(String token, Identification identification) {
        addToken(token,identification,30*60);
    }

    /**
     * 获取token对应信息
     * @param token
     * @return
     */
    @Override
    public Identification getIdentification(String token) {
        if(token==null)
            return null;

        if(tokenMap.containsKey(token)){
            return tokenMap.get(token);
        }

        Identification identification=(Identification) redisTemplate.opsForValue().get(TOKEN_PREFIX+token);
        if(identification!=null){
            tokenMap.put(token,identification);
        }

        return identification;
    }
}
